1. Field of the Invention
This invention relates to the verifying of code access control protocols, and particularly to the automatic verification of privilege-asserting and subject-executed code
2. Description of Background
Before our invention, conventionally within security systems where access control was based on stack inspection, when access to a protected resource was attempted all the callers on the stack must have exhibited the right to perform the security-sensitive operation of accessing the protected resource. Within security systems the implementation of privilege-asserting code allows for the stopping a stack inspection so that the callers of a trusted component are not required to exhibit a right to access a protected resource. The implementation of subject-executed code allows for the execution of code under the authority of a subject (a user or service). Additionally, permissions within a security system are typically defined as access rights.
Several problems can occur in relation to the implementation of privilege-asserting and subject-executed code. For example, in stack-inspection-based authorization systems (e.g., Microsoft™ .NET Common Language Runtime (CLR)), a developer can specify which permission can be implicitly granted to client code when privilege-asserting code is used. This aspect allows a developer to explicitly control what permissions the client code will receive as a result of invoking trusted code. However, other systems (e.g., Java™ 2) are not so fine grained when it comes to privilege-asserting code, and thus do not allow specifying the particular permission requirement from which the client is shielded. In such systems, a call to privilege-asserting code can shield client code from multiple permission requirements, which means that the client code is implicitly granted all the permissions that are regulated by the permission requirements. This behavior may not be intended and can easily lead to security flaws.
A similar principle dictates that a call to subject-executed code should only perform one security-sensitive operation. Thus, in the event that multiple security sensitive operations are to be performed the security operations should be performed under different subject-executed calls. However, enforcing this principle requires the writing of additional code in addition to possessing knowledge of what security-sensitive operations are going to be performed as a result of each function call. For this reason, developers tend to write subject-executed code that performs multiple security-sensitive operations. Detecting whether this principle has been violated or verifying that it has been respected is very difficult too, unless an automated tool is used to detect violations.
Often, after code is re-factored, it is possible that existing privilege-asserting or subject-executed code may become unnecessary; this occurs when existing calls to privilege-asserting code do not lead to authorization checks. From a performance perspective, this occurrence can be very expensive. From a security perspective, this occurrence can expose a system to security holes. When calls to privilege-asserting code are nested, only the call closer to the authorization check is necessary. The other calls are redundant and could lead to security holes and performance problems.
Typically, when calls to subject-executed code are nested, the most recently made call overwrites all the previous calls. The idea is that there can only be one subject associated with any thread of execution at any given time. In large and complex programs, it is often difficult, if not Impossible, to understand the interactions between nested calls to subject executed code unless an automated tool is available. Inappropriate usage of subject-executed code can lead to unintended results and security holes.
In some Implementations (such as Java™ 2), privilege-asserting code eliminates from a thread of execution any subject that had been previously associated with that thread. Many developers are not even aware of this behavior, which may lead to unintended consequences. A secure coding best practice suggests that privilege-asserting or subject executed code in a component should be placed as close as possible to the boundary between that component and other components. This helps in avoiding the execution of unintended privilege-asserting or subject executed code and assists in enforcing the principle that every call to privileged or subject-executed code should lead to only one security-sensitive resource at a time. However, many times, developers do not realize that the calls to privileged or subject-executed code that they make are not as close to the component's boundary as possible, especially because that boundary may still be unclear during development, or because code was subsequently re-factored.
No value generated in privilege-asserting code should flow to unauthorized code; a violation of this rule represents a confidentiality problem. Similarly, no value generated in unauthorized code should flow to privilege asserting code; a violation of this rule represents an integrity problem. The resolution of these problems by performing manual code inspection or testing is very difficult, time consuming and error prone. Therefore, there exists a need for an automatic technique for verifying that privileged and subject-executed code has been implemented as intended.